# -*- coding: utf-8 -*-
"""
Created on Sun Nov 11 10:09:10 2018

requests模块的使用,requests的底层实现就是urllib3

@author: hhao
"""


# -----------------获取页面---------------------


import requests


#在发起请求之间可以定义好session对象,用于记录cookie,这个对象代表一次用户会话,即从客户端浏览器连接股武器开始到客户端浏览器与服务器断开为止,会话能使得在跨请求时保持某些参数,如在同一个session实例发出的所有请求之间保持cookie.
#sess = requests.session()
#后面根据sess对象发起请求
#sess.get()/sess.post()

# 抓取页面,如果要将参数放在url中传递(查询字符串),则可以添加params参数,这里未展示post请求,其实post请求就是变get---post,然后在参数中增加data参数传递如表单数据等;如果需要使用代理则使用proxies参数来进行配置;如果在请求时出现验证SSL证书错误,则可考虑verify参数,设为False则不验证,默认True
#r = requests.get('https://book.douban.com/subject/1084336/comments/')
# 或者
r = requests.request('GET', 'https://book.douban.com/subject/1084336/comments/')

# 查看请求路径
print(r.url)

# 如果一个响应中包含cookie,那么可以利用cookie参数拿到
cookiejar = r.cookies  # 返回CookieJar对象
print(cookiejar)
cookiedict = requests.utils.dict_from_cookiejar(cookiejar)  # 将CookieJar转为字典
print(cookiedict)

"""
在发起请求时，还可以向url添加查询字符串
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://httpbin.org/get", params=payload)
print(r.url)
"""

# 状态码
print(r.status_code)


"""
请求发出后，Requests会基于HTTP头部对响应的编码做出有根据的推测（根据一个模块来猜）。当访问r.text时，
Requests会使用其推测的编码，你可以找出Requests使用了什么编码，并且能够使用encoding属性来改变它，如r.encoding = 'ISO-8859-1'
如果你改变了编码，每当你访问r.text时，Requests都将会使用r.encoding的新值。
你可能希望在使用特殊逻辑计算出文本的编码的情况下来修改编码。比如 HTTP 和 XML 自身可以指定编码。
这样的话，你应该使用 r.content 来找到编码，然后设置 r.encoding 为相应的编码。这样就能使用正确的编码解析 r.text 了。
在你需要的情况下，Requests 也可以使用定制的编码。如果你创建了自己的编码，并使用 codecs 模块进行注册，
你就可以轻松地使用这个解码器名称作为 r.encoding 的值， 然后由 Requests 来为你处理编码。
"""
#r.encoding = "utf-8"  #手动指定编码，不指定则靠猜

print(r.text)  # r.text获取网页Unicode格式数据，这个不指定encoding就靠猜

# 当前页面获取的是utf-8编码格式，r.content是二进制字符串/获取网页原始编码字符串，也可以获取图片、音视频等字节数据，这个不用猜,所以图片/音频等就用这个
print(r.content.decode('utf-8'))

print(r.text == r.content.decode('utf-8'))  # True

# 页面内容
#print(r.text)

# 将抓取到的内容写入本地文件中, 这里的./指的是Spyder指定的目录，而不是当前文件所在目录
"""
爬取网页数据后将网络数据流写入文件时会遇到几个编码问题，
    一、指定本py脚本文件本身的编码，如 # -*- coding: utf-8 -*-
    二、网络数据流的编码，比如获取网页，那么网络数据流的编码就是网页的编码，需要使用decode解码成unicode编码
    三、目标文件的编码，要将网络数据流的编码写入到新文件，那么需要指定新文件的编码
    即：
        1. 发送请求获取网页内容（不同的网页编码可能不一样）
        2. 程序处理时产生的字符串（可能会有不同编码）
        3. 保存结果需要同一编码（写入保存时的编码
不然可能会产生以下错误：
    Python UnicodeEncodeError: 'gbk' codec can't encode characte
"""
with open('./spider/spider/xiaowangzi.txt', 'w+', encoding='utf-8') as f:
    f.write(r.text)
# 或者
#with open('./spider/spider/xiaowangzi.txt', 'wb+') as f:
#    f.write(r.content)
  
#print(r.headers)

"""
注意： 为了反爬，有些网站会对Headers的User-Agent进行检测，需将headers信息传递给get函数的headers参数。进行身份伪装
      例如知乎，直接访问会返回400，加上headers参数后可正确返回
      主要是因为User-Agent在直接请求而不是通过浏览器请求时，是默认产生的（应该是没有，为空或者如urllib2默认的为Python-urllib/x.y 这里x和y是python主次版本号），会被暴露身份而阻止
re = requests.get('http://www.zhihu.com')
print(re.status_code)  # 400 

headers = {"User-Agent": "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11"}
re = requests.get('http://www.zhihu.com', headers = headers)
print(re.status_code)  # 200

反爬的策略还有很多，如需要登陆等

被JS渲染过的页面内容获取：可以通过浏览器的“开发者工具”功能寻找真正提供数据的页面等等

"""   

# -----------------获取页面中的评论---------------------

print('*'*50)
 
"""
Ipython:

from bs4 import BeautifulSoup

markup = '<p class="title"><b>The Little Prince</b></p>'

soup = BeautifulSoup(markup, 'lxml')

soup.b
Out[42]: <b>The Little Prince</b>

type(soup.b)
Out[43]: bs4.element.Tag

tag = soup.p

tag.name
Out[45]: 'p'

tag.attrs
Out[46]: {'class': ['title']}

tag.string
Out[47]: 'The Little Prince'

soup.find_all('b')
Out[48]: [<b>The Little Prince</b>]

type(tag.string)
Out[49]: bs4.element.NavigableString

""" 
    
    
import requests
from bs4 import BeautifulSoup


r = requests.get('https://book.douban.com/subject/1084336/comments/')

print(r.status_code)

#print(r.text)

soup = BeautifulSoup(r.text, 'lxml')  # 指定lxml解析器

#find_all返回的是一个列表，其中的元素是<p class="comment-content"><span class="short">谁能告诉俺，小王子这种书有什么好看的？</span></p>
pattern = soup.find_all('p', 'comment-content')

#print(pattern)

# 获取评论
for item in pattern:
    print(11111)
    # item----p标签    item.span----取到span标签   item.span.string----取到评论
    print(item.span.string)
    
import re

pattern_s = re.compile('<span class="user-stars allstar(.*?) rating"')

# 取出所偶评分
p = re.findall(pattern_s, r.text)

# 评分总和
sum1 = 0
for star in p:
    sum1 += int(star)
    
print(sum1)

   
    
